// ignore_for_file: constant_identifier_names

class DataConvert {
  static const List<String> HEX_CHAR_TABLE = [
    '0',
    '1',
    '2',
    '3',
    '4',
    '5',
    '6',
    '7',
    '8',
    '9',
    'A',
    'B',
    'C',
    'D',
    'E',
    'F'
  ];

  static String getHexString(List<int> raw, int offset, int count) {
    StringBuffer hex = StringBuffer();
    for (int i = offset; i < offset + count; i++) {
      int v = raw[i] & 0xFF;
      hex.write(HEX_CHAR_TABLE[v >> 4]);
      hex.write(HEX_CHAR_TABLE[v & 0xF]);
      hex.write(" ");
    }
    return hex.toString();
  }

  int strToInt(String str) {
    List<int> temp = getStringHex(str);
    int res = 0;
    for (int i = 0; i < temp.length; i++) {
      res |= temp[i] & 0xFF;
      if (i != temp.length - 1) {
        res <<= 8;
      }
    }
    return res;
  }

  String getIntByte(int v) {
    List<int> temp = [0, 0];
    temp[0] = ((v >> 8) & 0xFF);
    temp[1] = ((v) & 0xFF);
    String str = getHexString(temp, 0, 2);
    str = str.replaceAll(" ", "");
    return str;
  }

  static List<int> getStringHex(String st) {
    st = st.replaceAll(" ", "");
    st = st.replaceAll(":", "");
    st = st.replaceAll("-", "");

    List<String> buffer = st.split('');
    List<int> bytes = List.filled(buffer.length ~/ 2, 0);
    int index = 0;
    int bitSt = 0;

    if (buffer.length == 1) {
      bytes = List.filled(1, 0);
      bytes[0] = getASCvalue(buffer[0]);
      return bytes;
    }

    for (int i = 0; i < buffer.length; i++) {
      int v = buffer[i].codeUnitAt(0) & 0xFF;

      if (((v > 47) && (v < 58)) ||
          ((v > 64) && (v < 71)) ||
          ((v > 96) && (v < 103))) {
        if (bitSt == 0) {
          bytes[index] |= (getASCvalue(buffer[i]) * 16);
          bitSt = 1;
        } else {
          bytes[index] |= (getASCvalue(buffer[i]));
          bitSt = 0;
          index++;
        }
      } else if (v == 32) {
        if (bitSt == 0) {
          // do nothing
        } else {
          index++;
          bitSt = 0;
        }
      } else {
        continue;
      }
    }

    return bytes;
  }

  static int getASCvalue(String inStr) {
    int out = 0;
    switch (inStr) {
      case '0':
        out = 0;
        break;
      case '1':
        out = 1;
        break;
      case '2':
        out = 2;
        break;
      case '3':
        out = 3;
        break;
      case '4':
        out = 4;
        break;
      case '5':
        out = 5;
        break;
      case '6':
        out = 6;
        break;
      case '7':
        out = 7;
        break;
      case '8':
        out = 8;
        break;
      case '9':
        out = 9;
        break;
      case 'a':
        out = 10;
        break;
      case 'b':
        out = 11;
        break;
      case 'c':
        out = 12;
        break;
      case 'd':
        out = 13;
        break;
      case 'e':
        out = 14;
        break;
      case 'f':
        out = 15;
        break;
      case 'A':
        out = 10;
        break;
      case 'B':
        out = 11;
        break;
      case 'C':
        out = 12;
        break;
      case 'D':
        out = 13;
        break;
      case 'E':
        out = 14;
        break;
      case 'F':
        out = 15;
        break;
    }
    return out;
  }

  static String convertASCII(List<int> data) {
    int len = data.length;
    String msg = "";

    for (int i = 0; i < data.length; i++) {
      if (data[i] == 0) {
        len = i;
        break;
      }
    }

    try {
      msg = String.fromCharCodes(data.sublist(0, len));
      // Note: Dart doesn't have built-in GBK support, you might need a package
      // For GBK support, consider using the 'encoding' package
    } catch (e) {
      throw Exception("Unsupported encoding type.");
    }
    return msg;
  }

  static String bcdStr(int data) {
    StringBuffer hex = StringBuffer();
    int v = data & 0xFF;
    hex.write(HEX_CHAR_TABLE[v >> 4]);
    hex.write(HEX_CHAR_TABLE[v & 0xF]);
    return hex.toString();
  }

  static List<int> getASCIIbytes(String str) {
    // Note: This will use UTF-8 by default in Dart
    // For GBK support, consider using the 'encoding' package
    return str.codeUnits;
  }

  static List<int> getStrDBCD(String st) {
    st = st.replaceAll(" ", "");
    st = st.replaceAll(":", "");
    st = st.replaceAll("-", "");
    return getStringHex(st);
  }

  static String getAdd(List<int> add) {
    StringBuffer hex = StringBuffer();
    int i = add.length;
    while (i-- > 0) {
      int v = add[i] & 0xFF;
      hex.write(HEX_CHAR_TABLE[v >> 4]);
      hex.write(HEX_CHAR_TABLE[v & 0xF]);
    }
    return hex.toString();
  }

  static String getVal(List<int> mrecbuf, int offset) {
    List<int> val = [0, 0, 0, 0];
    val[0] = ((mrecbuf[offset + 0] & 0xff) - 0x33);
    val[1] = ((mrecbuf[offset + 1] & 0xff) - 0x33);
    val[2] = ((mrecbuf[offset + 2] & 0xff) - 0x33);
    val[3] = ((mrecbuf[offset + 3] & 0xff) - 0x33);

    int ival = convertByte(val[3]) * 10000;
    ival += convertByte(val[2]) * 100;
    ival += convertByte(val[1]);
    return "$ival.${dig(convertByte(val[0]))}";
  }

  static int convertByte(int inNum) {
    int v = inNum & 0xFF;
    int h = v >> 4;
    int l = v & 0xf;
    return h * 10 + l;
  }

  static String dig(int inNum) {
    if (inNum < 10) return "0$inNum";
    return "$inNum";
  }

  static int calCheckSum(List<int> data, int ys, int offset, int len) {
    int temp = ys & 0xff;
    for (int i = offset; i < offset + len; i++) {
      temp += data[i] & 0xff;
    }
    return temp & 0xff;
  }

  // Helper方法：字节转十六进制字符串
  static String bytesToHex(List<int> bytes) {
    return bytes
        .map((byte) => byte.toRadixString(16).padLeft(2, '0'))
        .join()
        .toUpperCase();
  }

  // 解析标签错误码
  static String getTagErrorCode(List<int> code) {
    String res = "";

    // 确保至少有3个字节
    if (code.length < 3) {
      return "错误码长度不足";
    }

    // 检查第一个字节的错误
    if ((code[0] & 1) != 0) {
      res += "传送方向错误";
    }

    if ((code[0] & 2) != 0) {
      res += "主从标志错误";
    }

    if ((code[0] & 4) != 0) {
      res += "错误标志异常";
    }

    if ((code[0] & 8) != 0) {
      res += "参数越限";
    }

    if ((code[0] & 16) != 0) {
      res += "无此功能";
    }

    if ((code[0] & 32) != 0) {
      res += "外设硬件异常";
    }

    // 检查第二个字节的错误
    if ((code[1] & 1) != 0) {
      res += "功率不足";
    }

    if ((code[1] & 2) != 0) {
      res += "权限不足";
    }

    if ((code[1] & 4) != 0) {
      res += "存储区溢出";
    }

    if ((code[1] & 8) != 0) {
      res += "存储区锁定";
    }

    if ((code[1] & 16) != 0) {
      res += "口令错误";
    }

    if ((code[1] & 32) != 0) {
      res += "未通过鉴别";
    }

    if ((code[1] & 64) != 0) {
      res += "安全认证失败";
    }

    // 检查第三个字节的错误
    if ((code[2] & 1) != 0) {
      res += "没有找到标签";
    }

    if ((code[2] & 2) != 0) {
      res += "标签无应答";
    }

    // 如果没有检测到任何错误，返回未知错误
    if (res.isEmpty) {
      res = "未知错误";
    }

    return res;
  }
}
